﻿
//变量记录表
//	string Name;		//变量名
//	string Type;		//变量类型
//	string ActiveType;	//变量的活动类型:  静态类型-static  局部类型-local  临时类型-temp
//	string VisitType;	//变量访问类型:  public private
//	int FunctionIndex;	//变量所在的函数索引
//	string UnitName;	//变量所在的元件名
//	int Location;		//变量的使用位置
//	int Level;			//变量所在的层数
//	bool isExist;		//变量是否存在
//	string Address;		//变量的地址
//	bool isComp;		//是否复合运算
//	bool isOut;			//是否编外的变量, 是的话 分配地址时忽略


namespace n_VarList
{
using System;
using n_ET;
using n_MemberType;
using n_UnitList;
using n_VarNode;

public static class VarList
{
	//软件启动初始化
	public static void Init()
	{
		NodeSet = new VarNode[ 20000 ];
	}
	
	//清除所有变量记录,重新编译
	public static void Clear()
	{
		length = 0;
	}
	
	//显示
	public static string Show()
	{
		string result = "";
		for( int i = 0; i < length; ++i ) {
			result += i + ": " + NodeSet[ i ].ToString() + "\n";
		}
		return result;
	}
	
	//添加变量
	public static int Add( VarNode v )
	{
		NodeSet[ length ] = v;
		++length;
		return length - 1;
	}
	
	//判断是否可以定义静态变量
	public static bool CanDefineStatic( string Name )
	{
		for( int i = 0; i < length; ++i ) {
			if( NodeSet[ i ].Name == Name ) {
				return false;
			}
		}
		return true;
	}
	
	//判断是否可以定义局部变量
	public static bool CanDefineLocal( string UnitName, int FunctionIndex, string Name )
	{
		for( int i = 0; i < length; ++i ) {
			if( NodeSet[ i ].FunctionIndex == FunctionIndex &&
				NodeSet[ i ].Name == Name &&
				NodeSet[ i ].IsExist ) {
				return false;
			}
			if( NodeSet[ i ].ActiveType == "static" && NodeSet[ i ].Name == UnitName + "." + Name ) {
				return false;
			}
		}
		return true;
	}
	
	//获取局部变量索引
	public static int GetLocalIndex( int FunctionIndex, string Name )
	{
		for( int i = length - 1; i >= 0; --i ) {
			if( NodeSet[ i ].Name == Name && NodeSet[ i ].FunctionIndex == FunctionIndex ) {
				return i;
			}
		}
		return -1;
	}
	
	//根据元件名获取元件直接索引
	public static int GetDirectStaticIndex( string Name )
	{
		for( int i = length - 1; i >= 0; --i ) {
			if( NodeSet[ i ].Name == Name && NodeSet[ i ].ActiveType == "static" ) {
				return i;
			}
		}
		return -1;
	}
	
	//获取索引
	public static int GetStaticIndex( string Name )
	{
		if( Name == null ) {
			return -1;
		}
		int VarIndex = GetDirectStaticIndex( Name );
		if( VarIndex == -1 ) {
			int SplitIndex = Name.LastIndexOf( "." );
			
			//数组中存在标签时会出现 -1 情况
			if( SplitIndex == -1 ) {
				return -1;
			}
			string UnitName = Name.Remove( SplitIndex );
			string VarName = Name.Remove( 0, SplitIndex );
			int UnitIndex = UnitList.GetIndex( UnitName );
			if( UnitIndex == -1 ) {
				return -1;
			}
			string NewName = UnitList.Get( UnitIndex ).UnitName + VarName;
			VarIndex = GetDirectStaticIndex( NewName );
		}
		if( VarIndex == -1 ) {
			return -1;
		}
		if( NodeSet[ VarIndex ].RealRefType == MemberType.RealRefType.Real ) {
			return VarIndex;
		}
		return GetStaticIndex( NodeSet[ VarIndex ].TargetMemberName );
	}
	
	//获取变量
	public static VarNode Get( int Index )
	{
		return NodeSet[ Index ];
	}
	
	//获取变量地址
	//返回 数字, null 或 虚拟地址( "#macro VarAddr Offset" )
	public static string GetAddr( int Index )
	{
		if( Index == -1 || NodeSet[ Index ].Address == null ) {
			return null;
		}
		if( NodeSet[ Index ].Address.StartsWith( "&index " ) ) {
			return GetIndexAddr( Index );
		}
		if( NodeSet[ Index ].Address.StartsWith( "&unitoffset " ) ) {
			return GetOffsetAddr( Index );
		}
		if( NodeSet[ Index ].Address.StartsWith( "&retarget " ) ) {
			return GetRetargetAddr( Index );
		}
		return NodeSet[ Index ].Address;
	}
	
	//获取索引变量的地址
	static string GetIndexAddr( int Index )
	{
		string[] Cut = NodeSet[ Index ].Address.Split( ' ' );
		int i = int.Parse( Cut[ 1 ] );
		
		//判断是否是自身
		if( i == Index ) {
			ET.WriteParseError( NodeSet[ Index ].Location, "不能引用自身地址: " + Cut[ 1 ] + "." + Cut[ 2 ] );
			return null;
		}
		//string StoreType1 = VarType.GetStoreType( NodeSet[ i ].Type );
		//string StoreType2 = VarType.GetStoreType( NodeSet[ Index ].Type );
		int Offset = int.Parse( Cut[ 2 ] );
		return "#macro " + i + " " + Offset;
	}
	
	//获取偏移地址
	static string GetOffsetAddr( int Index )
	{
		string[] MacroAddrCut = NodeSet[ Index ].Address.Split( ' ' );
		int i = VarList.GetStaticIndex( MacroAddrCut[ 1 ] );
		if( i == -1 ) {
			ET.WriteParseError( NodeSet[ Index ].Location, "变量引用出错:" + MacroAddrCut[ 1 ] );
			return null;
		}
		string MacroAddr = "#macro " + i + " " + MacroAddrCut[ 2 ];
		return MacroAddr;
	}
	
	//获取重定向地址
	static string GetRetargetAddr( int Index )
	{
		string[] MacroAddrCut = NodeSet[ Index ].Address.Split( ' ' );
		int i = VarList.GetStaticIndex( MacroAddrCut[ 1 ] );
		if( i == -1 ) {
			ET.WriteParseError( NodeSet[ Index ].Location, "引用已有变量地址出错:" + MacroAddrCut[ 1 ] );
			return null;
		}
		return NodeSet[ i ].Address;
	}
	
	//根据当前的级别标记无效的变量
	public static void ClearUselessVar( int CurrentLevel )
	{
		for( int i = length - 1; i >= 0;--i ) {
			if( NodeSet[ i ].Level > CurrentLevel ) {
				NodeSet[ i ].IsExist = false;
			}
		}
	}
	
	//获取在某个元件中的变量名集合
	public static string GetVarNames( string UnitName )
	{
		VarNode v = null;
		string result = null;
		
		for( int i = 0; i < length; ++i ) {
				v = NodeSet[ i ];
				if( //NodeSet[ i ].VisitType == MemberType.VisitType.Public &&
				
				NodeSet[ i ].ActiveType == "static" &&
				NodeSet[ i ].Name.IndexOf( "." ) != -1 &&
				NodeSet[ i ].UnitName == UnitName ) {
				string Name = NodeSet[ i ].Name;
				Name = Name.Remove( 0, Name.LastIndexOf( "." ) + 1 );
				if( !Name.StartsWith( "OS_" ) ) {
					result += Name + ";";
				}
			}
		}
		return result;
	}
	
	//遍历判断是否有互锁冲突的变量
	public static int GetLockError()
	{
		for( int i = 0; i < length; ++i ) {
			VarNode v = NodeSet[ i ];
			if( NodeSet[ i ].MultAccessError ) {
				return i;
			}
		}
		return -1;
	}
	
	//复位所有变量的存在属性
	public static void ResetAllVar()
	{
		for( int i = 0; i < length; ++i ) {
			NodeSet[ i ].IsExist = true;
		}
	}
	
	static VarNode[] NodeSet;	//节点集合
	public static int length;	//长度
}
}


